package com.cyh.core.framework.aop;

import com.cyh.core.framework.annotation.OperationLogDetail;
import com.cyh.core.framework.repository.log.LogRepository;
import com.cyh.core.framework.common.utils.JsonUtil;
import com.cyh.core.framework.common.utils.UUidUtil;
import com.cyh.core.framework.domain.entity.log.OperationLog;
import com.cyh.core.login.entity.User;
import com.cyh.core.login.service.user.IUserService;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Date;

// 关闭注解开启AOP
@Aspect
@Component
public class LogAspect {

    @Autowired
    LogRepository logRepository;

    @Autowired
    IUserService userService;

    @Pointcut("@annotation(com.cyh.core.framework.annotation.OperationLogDetail)")
    public void annotationPoinCut(){}

    @Around(value = "annotationPoinCut()")
    public Object aroundExec(ProceedingJoinPoint joinPoint) throws Throwable {
        Object res = null;
        long time = System.currentTimeMillis();
        try {
            res =  joinPoint.proceed();
            time = System.currentTimeMillis() - time;
            return res;
        } finally {
            try {
                OperationLogDetail(joinPoint,time,res);
            }catch (Exception e){
                System.out.println("LogAspect 操作失败：" + e.getMessage());
                e.printStackTrace();
            }
        }
    }

    private void OperationLogDetail(ProceedingJoinPoint joinPoint,long time,Object res){
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        Method method=signature.getMethod();
        if(method.isAnnotationPresent(OperationLogDetail.class)){
            OperationLogDetail logDetail=method.getAnnotation(OperationLogDetail.class);
            OperationLog operationLog = new OperationLog();
            operationLog.setLevel(logDetail.level());
            operationLog.setDetail(logDetail.detail());
            operationLog.setRunTime(time);
            operationLog.setReturnValue(JsonUtil.objectToJson(res));
            operationLog.setId(UUidUtil.UUID());
            operationLog.setArgs(JsonUtil.objectToJson(joinPoint.getArgs()));
            operationLog.setCreateTime(new Date());
            operationLog.setMethod(signature.getDeclaringTypeName() + "." + signature.getName());
            User currentUser = userService.getCurrentUser();
            if(currentUser == null){
                operationLog.setDetail("警告！当前操作没有具体用户信息;"+operationLog.getDetail());
                operationLog.setUserId(null);
            }else {
                operationLog.setUserId(currentUser.getId());
            }
            System.out.println("记录日志:" + operationLog.toString());
            try {
                logRepository.save(operationLog);
            }catch (Exception e){
                e.printStackTrace();
            }
        }

    }
}